package systemcontract

import (
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/consensus/congress/vmcaller"
	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/core/state"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/log"
	"github.com/ethereum/go-ethereum/params"
	"math"
	"math/big"
)

const (
	addressListV2Code = "0x608060405234801561001057600080fd5b50600436106101735760003560e01c80635cd8a76b116100de578063abbcbd3a11610097578063db6619b011610071578063db6619b0146104c1578063f851a440146104c9578063fb48270c146104d1578063ff0617df146104d957610173565b8063abbcbd3a14610455578063c4d66de81461046f578063cec0705a1461049557610173565b80635cd8a76b146103955780635eca4a701461039d5780636dfb5176146103c357806370b03fc5146103f257806389449301146103fa5780639e23c2091461042f57610173565b8063327564b611610130578063327564b6146102ec578063349cb711146102f4578063367f8a581461032357806343e0c73a146103445780634f608dd31461034c5780634fb9e9b71461036f57610173565b80630c47632714610178578063143d79b6146101dc578063158ef93e1461022c57806318c662121461024857806322fbf1e8146102a057806326782247146102c8575b600080fd5b6101a46004803603604081101561018e57600080fd5b50803590602001356001600160801b03166104e1565b60405180848152602001836001600160801b031681526020018260038111156101c957fe5b8152602001935050505060405180910390f35b610202600480360360208110156101f257600080fd5b50356001600160a01b03166105c7565b60405180831515815260200182600281111561021a57fe5b81526020019250505060405180910390f35b610234610649565b604080519115158252519081900360200190f35b610250610652565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561028c578181015183820152602001610274565b505050509050019250505060405180910390f35b6102c6600480360360208110156102b657600080fd5b50356001600160a01b03166106b4565b005b6102d06107b0565b604080516001600160a01b039092168252519081900360200190f35b6102346107bf565b6102c66004803603604081101561030a57600080fd5b5080356001600160a01b0316906020013560ff166107cd565b61032b610a00565b6040805163ffffffff9092168252519081900360200190f35b6102c6610a06565b6101a46004803603602081101561036257600080fd5b503563ffffffff16610adc565b6102c66004803603602081101561038557600080fd5b50356001600160a01b0316610bcb565b6102c6610c67565b610234600480360360208110156103b357600080fd5b50356001600160a01b03166110b6565b6102c6600480360360408110156103d957600080fd5b5080356001600160a01b0316906020013560ff166110d4565b6102506113cb565b6102346004803603606081101561041057600080fd5b5080359060208101356001600160801b0316906040013560ff1661142b565b6102c66004803603602081101561044557600080fd5b50356001600160a01b03166117b1565b61045d6118ab565b60408051918252519081900360200190f35b6102c66004803603602081101561048557600080fd5b50356001600160a01b03166118b1565b610234600480360360408110156104ab57600080fd5b50803590602001356001600160801b0316611930565b6102c6611d14565b6102d0611def565b6102c6611e04565b61045d611ebe565b6000828152600a602090815260408083206001600160801b038516845290915281205481908190801580159061051957506009548111155b156105b457610526612059565b6009600183038154811061053657fe5b60009182526020918290206040805160608101825260029093029091018054835260018101546001600160801b0381169484019490945291929083019060ff600160801b90910416600381111561058957fe5b600381111561059457fe5b9052508051602082015160409092015190965090945092506105c0915050565b50600092508291508190505b9250925092565b6001600160a01b038116600090815260056020908152604080832054600690925282205482911580159115159082906105fd5750805b156106115760016002935093505050610644565b81156106265760016000935093505050610644565b801561063a57600180935093505050610644565b6000809350935050505b915091565b60005460ff1681565b606060038054806020026020016040519081016040528092919081815260200182805480156106aa57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161068c575b5050505050905090565b6000546201000090046001600160a01b03163314610706576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b6001600160a01b03811660009081526002602052604090205460ff1615610764576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b6001600160a01b038116600081815260026020526040808220805460ff19166001179055517f058fdae480ed8e99b762bceb2d39835a68ee3a4789cd84e5c90cd59722ba02099190a250565b6001546001600160a01b031681565b600054610100900460ff1681565b6000546201000090046001600160a01b0316331461081f576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b600281600281111561082d57fe5b141561090e576001600160a01b038216600090815260056020526040902054610890576040805162461bcd60e51b815260206004820152601060248201526f1b9bdd081a5b88199c9bdb481b1a5cdd60821b604482015290519081900360640190fd5b6001600160a01b0382166000908152600660205260409020546108eb576040805162461bcd60e51b815260206004820152600e60248201526d1b9bdd081a5b881d1bc81b1a5cdd60921b604482015290519081900360640190fd5b6108fa60036005846000611ec4565b61090960046006846001611ec4565b6109f8565b600081600281111561091c57fe5b141561098e576001600160a01b03821660009081526005602052604090205461097f576040805162461bcd60e51b815260206004820152601060248201526f1b9bdd081a5b88199c9bdb481b1a5cdd60821b604482015290519081900360640190fd5b61090960036005846000611ec4565b6001600160a01b0382166000908152600660205260409020546109e9576040805162461bcd60e51b815260206004820152600e60248201526d1b9bdd081a5b881d1bc81b1a5cdd60921b604482015290519081900360640190fd5b6109f860046006846001611ec4565b505043600755565b60095490565b6000546201000090046001600160a01b03163314610a58576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b600054610100900460ff16610aa7576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48191a5cd8589b195960821b604482015290519081900360640190fd5b6000805461ff00191681556040517f733a7f99819dc7466bff56e7c0b6753b43b750a692f2a5bb4fe373815a0c7845908290a2565b60008060006009805490508463ffffffff1610610b35576040805162461bcd60e51b8152602060048201526012602482015271696e646578206f7574206f662072616e676560701b604482015290519081900360640190fd5b610b3d612059565b60098563ffffffff1681548110610b5057fe5b60009182526020918290206040805160608101825260029093029091018054835260018101546001600160801b0381169484019490945291929083019060ff600160801b909104166003811115610ba357fe5b6003811115610bae57fe5b905250805160208201516040909201519097919650945092505050565b6000546201000090046001600160a01b03163314610c1d576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517faefcaa6215f99fe8c2f605dd268ee4d23a5b596bbca026e25ce8446187f4f1ba90600090a250565b60085415610cbc576040805162461bcd60e51b815260206004820152601e60248201527f4f6e6c7920696e697469616c697a65206265666f726520616e79207573650000604482015290519081900360640190fd5b60075415610d11576040805162461bcd60e51b815260206004820152601e60248201527f4f6e6c7920696e697469616c697a65206265666f726520616e79207573650000604482015290519081900360640190fd5b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6001610d3c612059565b50604080516060810182528381526001600160801b0383811660208301908152600193830184815260098054958601815560005283516000805160206120988339815191526002909602958601908155915160008051602061207883398151915290950180546001600160801b031916959093169490941780835593519293849391929060ff60801b1916600160801b836003811115610dd857fe5b021790555050600980546000958652600a602090815260408088206001600160801b039788168952825280882083905580516060810182527f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987808252600293820184815260019383018481529386018755959099528051600080516020612098833981519152948402948501908155945160008051602061207883398151915290940180546001600160801b03191694909816939093178088559051919692955085945090919060ff60801b1916600160801b836003811115610eb757fe5b021790555050600980546000958652600a602090815260408088206001600160801b03888116808b52918452828a2085905582516060810184527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62808252948101928352600193810184815293860187559590995284516002909402600080516020612098833981519152810194855590516000805160206120788339815191529091018054919099166001600160801b031990911617808955905191979395508594509192909160ff60801b1916600160801b836003811115610f9757fe5b021790555050600980546000958652600a602090815260408088206001600160801b03888116808b52918452828a2085905582516060810184527f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb808252948101928352600193810184815293860187559590995284516002909402600080516020612098833981519152810194855590516000805160206120788339815191529091018054919099166001600160801b031990911617808955905191979395508594509192909160ff60801b1916600160801b83600381111561107757fe5b0217905550506009546000948552600a602090815260408087206001600160801b03909616875294905292909320919091555050436007819055600855565b6001600160a01b031660009081526002602052604090205460ff1690565b6000546201000090046001600160a01b03163314611126576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b6000546001600160a01b038381166201000090920416141561118f576040805162461bcd60e51b815260206004820152601d60248201527f63616e6e6f74206164642061646d696e20746f20626c61636b6c697374000000604482015290519081900360640190fd5b600281600281111561119d57fe5b1415611284576001600160a01b03821660009081526005602052604090205415611205576040805162461bcd60e51b8152602060048201526014602482015273185b1c9958591e481a5b88199c9bdb481b1a5cdd60621b604482015290519081900360640190fd5b6001600160a01b03821660009081526006602052604090205415611265576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e481a5b881d1bc81b1a5cdd60721b604482015290519081900360640190fd5b6112726003600584612016565b61127f6004600684612016565b611374565b600081600281111561129257fe5b1415611307576001600160a01b038216600090815260056020526040902054156112fa576040805162461bcd60e51b8152602060048201526014602482015273185b1c9958591e481a5b88199c9bdb481b1a5cdd60621b604482015290519081900360640190fd5b61127f6003600584612016565b6001600160a01b03821660009081526006602052604090205415611367576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e481a5b881d1bc81b1a5cdd60721b604482015290519081900360640190fd5b6113746004600684612016565b43600781905550816001600160a01b03167f4bb8845da5ed7c2df200814ba7a0f3db11326cc817cf9a042fa54d4e5f6f29bb82604051808260028111156113b757fe5b815260200191505060405180910390a25050565b606060048054806020026020016040519081016040528092919081815260200182805480156106aa576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161068c575050505050905090565b600080546201000090046001600160a01b0316331461147e576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b836114d0576040805162461bcd60e51b815260206004820152601d60248201527f6576656e745369676e6174757265206d757374206e6f7420656d707479000000604482015290519081900360640190fd5b6000836001600160801b03161161152e576040805162461bcd60e51b815260206004820152601f60248201527f636865636b20696e646578206d7573742067726561746572207468616e203000604482015290519081900360640190fd5b600082600381111561153c57fe5b1180156115555750600382600381111561155257fe5b11155b61159b576040805162461bcd60e51b8152602060048201526012602482015271696e76616c696420636865636b207479706560701b604482015290519081900360640190fd5b6000848152600a602090815260408083206001600160801b03871684529091529020548015611665576000600960018303815481106115d657fe5b90600052602060002090600202019050838160010160106101000a81548160ff0219169083600381111561160657fe5b0217905550857f07b8dde0de807efa8ecba675ef2be9d8af8f01e266085068e60c8e76837ee11a868660405180836001600160801b0316815260200182600381111561164e57fe5b81526020019250505060405180910390a2506117a2565b61166d612059565b6040518060600160405280878152602001866001600160801b0316815260200185600381111561169957fe5b905260098054600181018255600091909152815160029091026000805160206120988339815191528101918255602083015160008051602061207883398151915290910180546001600160801b039092166001600160801b03199092169190911780825560408401519394508493919060ff60801b1916600160801b83600381111561172157fe5b0217905550506009546000888152600a602090815260408083206001600160801b038b16808552908352928190209390935591519081528892507f441fbdf9d33c890abf8663a8fd49b8ee03e20ba4cce546dfa92d8bce8f1abf6b9188918891810182600381111561178f57fe5b81526020019250505060405180910390a2505b50504360085560019392505050565b6000546201000090046001600160a01b03163314611803576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b6001600160a01b03811660009081526002602052604090205460ff16611862576040805162461bcd60e51b815260206004820152600f60248201526e3737ba1030903232bb32b637b832b960891b604482015290519081900360640190fd5b6001600160a01b038116600081815260026020526040808220805460ff19169055517f110a48e3e347ae018d4d40446e4e917b416f912dec489da19b4507bb9bb18cd49190a250565b60075481565b60005460ff16156118ff576040805162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b6000805460ff196001600160a01b03909316620100000262010000600160b01b031990911617919091166001179055565b600080546201000090046001600160a01b03163314611983576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b826119d5576040805162461bcd60e51b815260206004820152601d60248201527f6576656e745369676e6174757265206d757374206e6f7420656d707479000000604482015290519081900360640190fd5b6000826001600160801b031611611a33576040805162461bcd60e51b815260206004820152601f60248201527f636865636b20696e646578206d7573742067726561746572207468656e203000604482015290519081900360640190fd5b6000838152600a602090815260408083206001600160801b0386168452909152902054611a98576040805162461bcd60e51b815260206004820152600e60248201526d1c9d5b19481b9bdd08195e1a5cdd60921b604482015290519081900360640190fd5b6000838152600a602090815260408083206001600160801b038616845290915281208054919055611ac7612059565b60096001830381548110611ad757fe5b60009182526020918290206040805160608101825260029093029091018054835260018101546001600160801b0381169484019490945291929083019060ff600160801b909104166003811115611b2a57fe5b6003811115611b3557fe5b9052506009549091508214611c6357611b4c612059565b600980546000198101908110611b5e57fe5b60009182526020918290206040805160608101825260029093029091018054835260018101546001600160801b0381169484019490945291929083019060ff600160801b909104166003811115611bb157fe5b6003811115611bbc57fe5b8152505090508060096001850381548110611bd357fe5b6000918252602091829020835160029290920201908155908201516001820180546001600160801b0319166001600160801b03909216919091178082556040840151919060ff60801b1916600160801b836003811115611c2f57fe5b02179055505081516000908152600a60209081526040808320948201516001600160801b0316835293905291909120839055505b6009805480611c6e57fe5b60008281526020808220600260001990940193840201918255600191909101805470ffffffffffffffffffffffffffffffffff19169055915581518282015160408085015190516001600160801b038316815292937f89fdef5ae498cf51728b26200045df6c8a41d44fee8191778fa2bcb855a725de93908101826003811115611cf457fe5b81526020019250505060405180910390a250504360085550600192915050565b6000546201000090046001600160a01b03163314611d66576040805162461bcd60e51b815260206004820152600a60248201526941646d696e206f6e6c7960b01b604482015290519081900360640190fd5b600054610100900460ff1615611db5576040805162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e48195b98589b1959608a1b604482015290519081900360640190fd5b6000805461ff0019166101001781556040516001917f733a7f99819dc7466bff56e7c0b6753b43b750a692f2a5bb4fe373815a0c784591a2565b6000546201000090046001600160a01b031681565b6001546001600160a01b03163314611e54576040805162461bcd60e51b815260206004820152600e60248201526d4e65772061646d696e206f6e6c7960901b604482015290519081900360640190fd5b600180546000805462010000600160b01b0319166001600160a01b0380841662010000908102929092178084556001600160a01b03199094169094556040519204909216917f7ce7ec0b50378fb6c0186ffb5f48325f6593fcb4ca4386f21861af3129188f5c91a2565b60085481565b6001600160a01b03821660009081526020849052604081208054919055845460001991820191018114611f9457845485906000198101908110611f0357fe5b9060005260206000200160009054906101000a90046001600160a01b0316858281548110611f2d57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080600101846000878481548110611f6e57fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020555b84805480611f9e57fe5b600082815260209020810160001990810180546001600160a01b03191690550190556040516001600160a01b038416907f91b762fba034b39c8b14c1e6463a15b1f4c211dcd0023f7fa2f4ae2928dfc44d90849080826002811115611fff57fe5b815260200191505060405180910390a25050505050565b82546001810184556000848152602080822090920180546001600160a01b039094166001600160a01b031990941684179055935491845291909152604090912055565b6040805160608101825260008082526020820181905290918201529056fe6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b06e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7afa264697066735822122009f0ff6f52d3a0516e121ef0f14d29cd49d5d29cde3e6a90ccb20cea35bc298764736f6c634300060c0033"
)

type hardForkAddressListV2 struct {
}

func (s *hardForkAddressListV2) GetName() string {
	return AddressListContractName
}

func (s *hardForkAddressListV2) Update(config *params.ChainConfig, height *big.Int, state *state.StateDB) (err error) {
	contractCode := common.FromHex(addressListV2Code)

	//write addressListV2Code to sys contract
	state.SetCode(AddressListContractAddr, contractCode)
	log.Debug("Upgrade code to system contract account", "addr", AddressListContractAddr.String(), "code", addressListV2Code)

	return
}

func (s *hardForkAddressListV2) Execute(state *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig) (err error) {

	method := "initializeV2"
	data, err := GetInteractiveABI()[AddressListContractName].Pack(method)
	if err != nil {
		log.Error("Can't pack data for initialize", "error", err)
		return err
	}

	msg := vmcaller.NewLegacyMessage(header.Coinbase, &AddressListContractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false)
	_, err = vmcaller.ExecuteMsg(msg, state, header, chainContext, config)

	return
}
